package com.yn.club.common.util;

import lombok.Getter;
import lombok.Setter;
import org.springframework.core.MethodParameter;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

/**
 * @author Bing
 */
@Setter
@Getter
public class PageReqArgumentResolver implements HandlerMethodArgumentResolver {

  private static final String PAGE_INDEX_PARAMETER = "pageIndex";
  private static final String PAGE_SIZE_PARAMETER = "pageSize";

  private String pageIndexParameter;
  private String pageSizeParameter;
  private int maxPageSize = 2000;

  public PageReqArgumentResolver() {
    this(PAGE_INDEX_PARAMETER, PAGE_SIZE_PARAMETER);
  }

  public PageReqArgumentResolver(String pageIndexParameter, String pageSizeParameter) {
    this.pageIndexParameter = pageIndexParameter;
    this.pageSizeParameter = pageSizeParameter;
  }

  @Override
  public boolean supportsParameter(MethodParameter parameter) {
    return PageReq.class.isAssignableFrom(parameter.getParameterType());
  }

  @Override
  public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer mavContainer,
      NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
    String pageIndexStr = webRequest.getParameter(pageIndexParameter);
    String pageSizeStr = webRequest.getParameter(pageSizeParameter);

    if (!StringUtils.hasText(pageIndexStr)) {
      return PageReq.unPage();
    }

    int pageIndex = obtainPageIndex(pageIndexStr);
    int pageSize = obtainPageSize(pageSizeStr);

    return PageReq.of(pageIndex, pageSize);
  }

  private int obtainPageIndex(String pageIndexStr) {
    int pageIndex = 1;
    try {
      pageIndex = Integer.parseInt(pageIndexStr);
    } catch (NumberFormatException ignored) {
    }
    if (pageIndex < 1) {
      pageIndex = 1;
    }
    return pageIndex;
  }

  private int obtainPageSize(String pageSizeStr) {
    int pageSize = 20;
    try {
      pageSize = Integer.parseInt(pageSizeStr);
    } catch (NumberFormatException ignored) {
    }
    if (pageSize < 0) {
      pageSize = 20;
    }
    if (pageSize > maxPageSize) {
      pageSize = maxPageSize;
    }
    return pageSize;
  }
}
